package com.nlp.automata;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
 * https://blog.csdn.net/Spring_East/article/details/78608187
 * @author ygsong.abcft
 *
 */
public class NFA {
	
	private NFAState startState = null;
	
	public NFAState getStartState() {
		return startState;
	}
	
	/**
	 * 接收状态acceptingStates
	 */
	private Set<NFAState> acceptingStates = new HashSet<>();
	
	public Set<NFAState> getAcceptingStates() {
		return acceptingStates;
	}
	public boolean accept(NFAState state) {
		return this.acceptingStates.contains(state);
	}
	
	public void addAcceptingState(NFAState state) {
		this.acceptingStates.add(state);
	}
	
	public NFA() {
		this(new NFAState(), new NFAState());
	}
	
	public NFA(NFAState startState) {
		this(startState, new NFAState());
	}
	
	public NFA(NFAState startState, NFAState acceptingState) {
		this.startState = startState;
		this.addAcceptingState(acceptingState);
	}
	
	/**
	 * 在上面的NFAState类实现中，新的状态节点时在添加迁移映射的过程中生成的
	 * 这个过程中NFA并没有介入，因此NFA类不能直接得到状态集S的成员
	 * 而是需要从状态startState开始，独断迭代找出所有的状态节点
	 */
	protected void getStateSet(NFAState current, Set<NFAState> states) {
		if (states.contains(current)) {
			return;
		}
		states.add(current);
		
		Iterator<NFAState> it = current.getNextStates().iterator();
		while (it.hasNext()) {
			this.getStateSet(it.next(), states);
		}
		
		it = current.getEpsilonTransition().iterator();
		while (it.hasNext()) {
			this.getStateSet(it.next(), states);
		}
	}
	
	public Set<NFAState> getStateSet(){
		Set<NFAState> states = new HashSet<>();
		this.getStateSet(this.getStartState(), states);
		return states;
	}

}
